home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Developer Essentials / DTS Sample Code / System 7.0 Samples / MacShell / Utils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-04  |  9.6 KB  |  423 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** Program:     MacShell
  5. ** File:        utils.c
  6. ** Written by:  Eric Soldan
  7. **
  8. ** Copyright © 1990-1991 Apple Computer, Inc.
  9. ** All rights reserved.
  10. */
  11.  
  12.  
  13.  
  14. /*****************************************************************************/
  15.  
  16.  
  17.  
  18. #include "MacShell.h"            /* Get the MacShell includes/typedefs, etc.    */
  19. #include "MacShellCommon.h"        /* Get the stuff in common with rez.        */
  20. #include "MacShell.protos"        /* Get the prototypes for MacShell.            */
  21.  
  22. #ifndef __STRING__
  23. #include <String.h>
  24. #endif
  25.  
  26. #ifndef __RESOURCES__
  27. #include <Resources.h>
  28. #endif
  29.  
  30. #ifdef THINK_C
  31. #include "Utilities.h"
  32. #else
  33. #ifndef __UTILITIES__
  34. #include <Utilities.h>
  35. #endif
  36. #endif
  37.  
  38.  
  39.  
  40. #define BASE 10
  41.  
  42.  
  43.  
  44. /*****************************************************************************/
  45.  
  46.  
  47.  
  48. #pragma segment Main
  49. void    appendi2cstr(char *cstr, short i)
  50. {
  51.     i2cstr(cstr + strlen(cstr), i);
  52. }
  53.  
  54.  
  55.  
  56. /*****************************************************************************/
  57.  
  58.  
  59.  
  60. #pragma segment Main
  61. short    appendi2pstr(char *pstr, short i)
  62. {
  63.     short    j;
  64.  
  65.     j = 0;
  66.     if (i >= BASE) j = appendi2pstr(pstr, i / BASE);
  67.     pstr[++*pstr] = "0123456789ABCDEF"[i - j];
  68.     return(BASE * i);
  69. }
  70.  
  71.  
  72.  
  73. /*****************************************************************************/
  74.  
  75.  
  76.  
  77. #pragma segment Main
  78. short    i2cstr(char *cstr, short i)
  79. {
  80.     short    j;
  81.  
  82.     cstr[1] = j = 0;
  83.     if (i >= BASE)
  84.         j = i2cstr(cstr + 1, i / BASE);
  85.     *cstr = "0123456789ABCDEF"[i - j];
  86.     return(BASE * i);
  87. }
  88.  
  89.  
  90.  
  91. /*****************************************************************************/
  92.  
  93.  
  94.  
  95. #pragma segment Main
  96. void    i2pstr(char *pstr, short i)
  97. {
  98.     *pstr = 0;
  99.     appendi2pstr(pstr, i);
  100. }
  101.  
  102.  
  103.  
  104. /*****************************************************************************/
  105.  
  106.  
  107.  
  108. #pragma segment Main
  109. void    pstrcat(char *d, char *s)
  110. {
  111.     short    i;
  112.  
  113.     for (i = 0; i < s[0];)
  114.         d[++d[0]] = s[++i];
  115. }
  116.  
  117.  
  118.  
  119. /*****************************************************************************/
  120.  
  121.  
  122.  
  123. #pragma segment Main
  124. void    pstrcpy(char *d, char *s)
  125. {
  126.     short    i;
  127.  
  128.     i = *s;
  129.     do {
  130.         d[i] = s[i];
  131.     } while (i--);
  132. }
  133.  
  134.  
  135.  
  136. /*****************************************************************************/
  137.  
  138.  
  139.  
  140. #pragma segment Main
  141. short    GetHexByte(char *cptr)
  142. {
  143.     short    val, i, chr;
  144.  
  145.     for (val = 0, i = 0; i < 2; ++i) {
  146.         chr = cptr[i];
  147.         if (chr == '=') return(cptr[++i]);
  148.         if (chr > 'F') chr -= 0x20;
  149.         if (chr > '9') chr -= ('A' - '9' - 1);
  150.         val = (val << 4) + chr - '0';
  151.     }
  152.     return(val);
  153. }
  154.  
  155.  
  156.  
  157. /*****************************************************************************/
  158.  
  159.  
  160.  
  161. #pragma segment Main
  162. pascal Boolean    alertFilter(DialogPtr dlg, EventRecord *event, short *item)
  163. {
  164.     short    what, theChr, theMod, handled;
  165.  
  166.     what = event->what;
  167.     if (event->what == keyDown) {
  168.         theChr = event->message   & charCodeMask;
  169.         theMod = event->modifiers & keyCodeMask;
  170.         if ((theChr != 0x0D) && (theChr != 0x03))        event->what = nullEvent;
  171.         if (theMod & (cmdKey + optionKey + controlKey)) event->what = nullEvent;
  172.     }
  173.     handled = keyEquivFilter(dlg, event, item);
  174.     event->what = what;
  175.     return(handled);
  176. }
  177.  
  178.  
  179.  
  180. /*****************************************************************************/
  181.  
  182.  
  183.  
  184. /* This code expects the key equivalents to be in item #2, which is a StatText
  185. ** item that is located so the text is outside of the dialog.  This allows us
  186. ** to put key equivalent information in the resource fork, so the key
  187. ** equivalents are localizable.
  188. **
  189. ** An example save changes before closing or quitting res source with
  190. ** keyEquiv info would look like:
  191. **
  192. ** resource 'DITL' (rYesNoCancel, purgeable) {
  193. **     {
  194. **         {71, 315, 91, 367}, Button     { enabled, "Save" },
  195. **         {0, -1000, 20, 2},  StaticText { disabled,
  196. **             "=S190001,=s190001,=D190003,=d190003,=.190104,1B190004" },
  197. **         {71, 80, 91, 162},  Button { enabled, "Don’t Save" },
  198. **         {71, 244, 91, 302}, Button { enabled, "Cancel" },
  199. **         {11, 78, 61, 366},  StaticText { disabled,
  200. **             "Save changes to the document “^0” before ^1?" },
  201. **         {11, 23, 43, 55},        Icon { disabled, 2 }
  202. **     }
  203. ** };
  204. **
  205. ** The document name would be the string for param #0.
  206. ** The text "closing" or "quitting" would be the string for param #1.
  207. **
  208. ** The keyEquiv entry is item #2, which has a rect that pushes it out of the
  209. ** dialog.  The string info is interpreted as to what the key/modifier combo
  210. ** is, and what dialog item it relates to.
  211. **
  212. ** A single key equiv entry is 8 characters.  Entries are separated by commas.
  213. **
  214. ** If the first character of an entry is an =, then the next character is the 
  215. ** key.  If the first character isn't an =, then the first two characters are 
  216. ** the hex value of the key.  (Ex:  =S or =s for save, 1B for ESC.)
  217. **
  218. ** If the key pressed is the same as the key value for any of the entries, then 
  219. ** the next two characters are the hex value for which modifiers to test.  This
  220. ** modifier test value is anded with the modifier.  The result is then compared 
  221. ** to the value of the next two hex digits.  If they are equal, then the 
  222. ** modifiers are correct, as well as the key.  If this is so, we have a winner.
  223. **
  224. ** "=S190001,=s190001,=D190003,=d190003,=.190104,1B190004"
  225. **
  226. ** The above string breaks down as follows:
  227. ** =S190001  =S  if event keypress is an S, check the modifier values
  228. **           19  check controlKey/optionKey/cmdKey
  229. **           00  all modifiers we are testing for should be false
  230. **           01  if above is true, keypress maps to item # 1
  231. ** =s190001  Same as =S, but lowercase
  232. ** =D190001  Same as =S, but maps to item #3
  233. ** =d190001  Same as =D, but lowercase
  234. ** =.190104  =.  if event keypress is a period, check the modifier values
  235. **           19  check controlKey/optionKey/cmdKey
  236. **           01  controlKey/optionKey should be false, cmdKey should be true
  237. **           04  if above is true, keypress maps to item # 4
  238. ** 1B190004  1B  if event keypress is an ESC, check the modifier values
  239. **           19  check controlKey/optionKey/cmdKey
  240. **           00  all modifiers we are testing for should be false
  241. **           04  if above is true, keypress maps to item # 4
  242. */
  243.  
  244. #pragma segment Main
  245. pascal Boolean    keyEquivFilter(DialogPtr dlg, EventRecord *event, short *item)
  246. {
  247.     short    itemType;
  248.     Handle    itemHndl;
  249.     Rect    itemRect;
  250.     Str255    itemText;
  251.     short    i, theChr, theMod, equivChr, modMask, modVal, itemNum;
  252.     long    tick;
  253.  
  254.     if (event->what == updateEvt) {
  255.         if (dlg == (DialogPtr)event->message) OutlineDialogItem(dlg, 1);
  256.         return(false);
  257.     }
  258.  
  259.     if (event->what != keyDown) return(false);
  260.  
  261.     itemNum = 0;
  262.  
  263.     theChr = event->message   & charCodeMask;
  264.     theMod = event->modifiers & keyCodeMask;
  265.  
  266.     if ((theChr == 0x0D) || (theChr == 0x03)) {        /* If return or enter... */
  267.         if (!(theMod & (cmdKey + optionKey + controlKey))) itemNum = 1;
  268.     }        
  269.     else {
  270.  
  271.         GetDItem(dlg, 2, &itemType, &itemHndl, &itemRect);
  272.         GetIText(itemHndl, itemText);
  273.  
  274.         for (i = 1; i <= *itemText; i += 9) {
  275.             equivChr = GetHexByte((char *)(itemText + i));
  276.             modMask  = GetHexByte((char *)(itemText + i + 2)) << 8;
  277.             modVal   = GetHexByte((char *)(itemText + i + 4)) << 8;
  278.             itemNum  = GetHexByte((char *)(itemText + i + 6));
  279.             if (theChr == equivChr)
  280.                 if ((theMod & modMask) == modVal) break;
  281.             itemNum = 0;
  282.         }
  283.     }
  284.  
  285.     if (itemNum) {
  286.         GetDItem(dlg, itemNum, &itemType, &itemHndl, &itemRect);
  287.         HiliteControl((ControlHandle)itemHndl, 1);
  288.         tick = TickCount();
  289.         while (TickCount() < tick + 10);
  290.         HiliteControl((ControlHandle)itemHndl, 0);
  291.         *item = itemNum;
  292.         return(true);
  293.     }
  294.  
  295.     return(false);
  296. }
  297.  
  298.  
  299.  
  300. /*****************************************************************************/
  301.  
  302.  
  303.  
  304. #pragma segment Main
  305. void    OffsetControl(ControlHandle ctl, short dx, short dy)
  306. {
  307.     Rect    ctlRect;
  308.  
  309.     ctlRect = (*ctl)->contrlRect;
  310.     MoveControl(ctl, ctlRect.left + dx, ctlRect.top + dy);
  311. }
  312.  
  313.  
  314.  
  315. /*****************************************************************************/
  316.  
  317.  
  318.  
  319. #pragma segment Main
  320. void    DoDrawGrowIcon(WindowPtr window, Boolean horLine, Boolean verLine)
  321. {
  322.     WindowPtr    oldPort;
  323.     Rect        rct;
  324.     RgnHandle    oldClip, newClip;
  325.  
  326.     GetPort(&oldPort);
  327.     SetPort(window);
  328.  
  329.     rct = window->portRect;
  330.     rct.left = rct.right  - 15;
  331.     rct.top  = rct.bottom - 15;
  332.  
  333.     if (window != FrontWindow()) {
  334.         FrameRect(&rct);
  335.         ++rct.top;
  336.         ++rct.left;
  337.         EraseRect(&rct);
  338.         SetPort(oldPort);
  339.         return;
  340.     }
  341.  
  342.     oldClip = NewRgn();
  343.     newClip = NewRgn();
  344.  
  345.     if (horLine) rct.left = window->portRect.left;
  346.     if (verLine) rct.top  = window->portRect.top;
  347.     RectRgn(newClip, &rct);
  348.  
  349.     GetClip(oldClip);
  350.     SetClip(newClip);
  351.     DrawGrowIcon(window);        /* Draw grow icon without scrollbar lines. */
  352.  
  353.     SetClip(oldClip);
  354.     DisposeRgn(oldClip);
  355.     DisposeRgn(newClip);
  356.  
  357.     SetPort(oldPort);
  358. }
  359.  
  360.  
  361.  
  362. /*****************************************************************************/
  363.  
  364.  
  365.  
  366. #pragma segment Main
  367. void    DoDrawControls(WindowPtr window, Boolean scrollBarsOnly)
  368. {
  369.     ControlHandle    ctl;
  370.  
  371.     ctl = ((WindowPeek)window)->controlList;
  372.     while (ctl) {
  373.         DoDraw1Control(ctl, scrollBarsOnly);
  374.         ctl = (*ctl)->nextControl;
  375.     }
  376. }
  377.  
  378.  
  379.  
  380. /*****************************************************************************/
  381.  
  382.  
  383.  
  384. #pragma segment Main
  385. void    DoDraw1Control(ControlHandle ctl, Boolean scrollBarsOnly)
  386. {
  387.     Boolean            front;
  388.     WindowPtr        window, oldPort;
  389.     Rect            rct;
  390.     ControlHandle    scrollCtl;
  391.     static Handle    scrollProc;
  392.  
  393.     front = ((window = (*ctl)->contrlOwner) == FrontWindow());
  394.  
  395.     if (!scrollProc) {
  396.         SetRect(&rct, 0, 0, 16, 100);
  397.         scrollCtl = NewControl(window, &rct, nil, false, 0, 0, 0, scrollBarProc, 0);
  398.         if (scrollCtl) {
  399.             scrollProc = (*scrollCtl)->contrlDefProc;
  400.             DisposeControl(scrollCtl);
  401.         }
  402.     }
  403.  
  404.     if ((*ctl)->contrlDefProc == scrollProc) {
  405.         if (front) Draw1Control(ctl);
  406.         else {
  407.             if ((*ctl)->contrlVis) {
  408.                 GetPort(&oldPort);
  409.                 SetPort(window);
  410.                 rct = (*ctl)->contrlRect;
  411.                 FrameRect(&rct);
  412.                 InsetRect(&rct, 1, 1);
  413.                 EraseRect(&rct);
  414.                 SetPort(oldPort);
  415.             }
  416.         }
  417.     }
  418.     else if (!scrollBarsOnly) Draw1Control(ctl);
  419. }
  420.  
  421.  
  422.  
  423.